;###########################
;## ASOCIACION HEURISTICA ##
;###########################
(defmodule modulo-asociacion
    (import MAIN ?ALL)
	(import modulo-obtencion ?ALL)
	(import modulo-abstraccion ?ALL)
    (export ?ALL)
)
(defglobal ?*PUNT_BENEFICIOS* = 5)
(defglobal ?*PUNT_OBJETIVOS* = 10)

(deftemplate recomendacion
	(slot estado)
	(multislot ejercicios)
	(slot intensidad (type SYMBOL) (allowed-values suave intensa))
	(slot descansos (type SYMBOL) (allowed-values normal extra))
	(slot dificultad (type SYMBOL) (allowed-values baja alta))
)


;# Determinar de que forma es recomendable realizar los
;#  ejercicios en base al perfil de la persona

(defrule crear-recomendacion-estandar
	(not (recomendacion))
	=>
	(assert (recomendacion (estado defecto) (intensidad intensa) (descansos normal) (dificultad baja)))
)

(defrule gente-mayor-no-deportista
	?r <- (recomendacion (estado defecto))
	(edad mayor)
	(not (gasto-energetico deportista))
	=>
	(modify ?r (estado adaptada) (intensidad suave))
)

(defrule gente-sedentaria
	?r <- (recomendacion (estado defecto))
	(gasto-energetico sedentaria)
	=>
	(modify ?r (estado adaptada) (intensidad suave) (descansos extra))
)

(defrule gente-elite
	?r <- (recomendacion (estado defecto))
	(gasto-energetico deportista)
	(estado-nutricional normal)
	(not (edad mayor))
	=>
	(modify ?r (estado adaptada) (dificultad alta))
)

;# Se descartan los ejercicios que se ha determinado que no se pueden hacer por probelmas de salud
(defrule eliminarEjercicios
	(declare (salience 1))
	(instancia-persona ?persona)
	?problema <- (object (is-a ProblemaSalud))
	?ejercicio <- (object (is-a Ejercicio) (perjudica $?problemasEjericio) (nombreEjercicio ?nombre))
	(test (member$ (instance-name ?problema) $?problemasEjericio))
	(test (member$ (instance-name ?problema) (send ?persona get-problemas)))
	=>
	;# Para este caso los eliminamos directamente porque ya no serviran para nada
	(send ?ejercicio delete)
	(printout t "No puede hacer " ?nombre " por problemas de salud." crlf)
)

(defrule eliminarPiscina
	?tipos <- (tipos-ejercicios (filtrado no) (lista $?lista))
	(instancia-persona ?persona)
	(test (not (send ?persona get-sabeNadar)))
	=>
	(modify ?tipos (filtrado si) (lista $?lista (delete$ $?lista 1 1)))
)

;# Ya no hace falta, se calcula de otra manera, pero a si se muestra por pantalla
(defrule eliminarEjercicioPiscina
	(declare (salience 1))
	(instancia-persona ?persona)
	?ejercicio <- (object (is-a EjercicioPiscina) (requiereNadar TRUE) (nombreEjercicio ?nombre))
	(test (not (send ?persona get-sabeNadar) ))
	=>
	;# Para este caso los eliminamos directamente porque ya no serviran para nada
	(send ?ejercicio delete)
	(printout t "No puede hacer " ?nombre " porque no sabe nadar." crlf)
)


;# Incrementamos la prioridad a todos los ejercicios que benefician alguno de
;# los problemas de salud que tiene la persona
(defrule ejercicios-beneficio
	(declare (salience 0))
	?problema <- (object (is-a ProblemaSalud))
	(instancia-persona ?persona)
	(test (member$ (instance-name ?problema) (send ?persona get-problemas)))
	?ejercicio <- (object (is-a Ejercicio) (beneficia $?beneficios))
	(test  (member$ (instance-name ?problema) $?beneficios))
	=>
	(send ?ejercicio put-puntuacion (+ ?*PUNT_BENEFICIOS* (send ?ejercicio get-puntuacion)))
)

;# Incrementamos la prioridad a todos los ejercicios que cumplen alguno de
;# los objetivos de la persona
(defrule ejercicios-objetivo
	(declare (salience 0))
	?objetivo <- (object (is-a Objetivo))
	(instancia-persona ?persona)
	(test (member (instance-name ?objetivo) (send ?persona get-objetivos)))
	?ejercicio <- (object (is-a Ejercicio) (satisface $?beneficios))
	(test  (member$ (instance-name ?objetivo) $?beneficios))
	=>
	(send ?ejercicio put-puntuacion (+ ?*PUNT_OBJETIVOS* (send ?ejercicio get-puntuacion)))
)

;(defrule chivato
;	(declare (salience -1))
;	?ejercicio <- (object (is-a Ejercicio))
;	=>
;	(send ?ejercicio imprimir)
;)

;(defrule prueba
;	?objetivo <- (object (is-a Objetivo))
;	?ejercicio <- (object (is-a Ejercicio) (satisface $?beneficios) (nombreEjercicio ?nombre))
;	(test (member$ (instance-name ?objetivo) $?beneficios))
;	(test (member$ (instance-name ?objetivo) (send ?persona get-objetivos)))
;	=>
;	(printout t "Ejercicio " ?nombre " satisface un objetivo." crlf)
;)

;## CAMBIO DE MODULO ##########################################################
(defrule end-asociacion
	(declare (salience -10000))
	=>
	(printout t "[END ASOCICACION]" crlf crlf "[RESULTADOS]" crlf)
	(focus modulo-resultados)
)
